package main

import (
	"bufio"
	"bytes"
	"embed"
	"flag"
	"fmt"
	"github.com/dreadl0ck/tlsx"
	"github.com/google/gopacket"
	"net/http"
	"os"
	"packet_capture/bean"
	"packet_capture/net"
	"packet_capture/web"
	"strconv"
	"strings"
)

//go:embed static/*
var staticFS embed.FS //static目录嵌入staticFS变量

var util = net.IpUtil{}.NewQQZend()

func startPacket(name string, localIp string) {
	localIpData := util.SearchQQZend(localIp)
	net.GetDeviceData(name, func(packet gopacket.Packet) {
		destData := net.GetDestData(packet)
		if destData != nil {
			search := util.SearchQQZend(destData.Ip)
			if search.Latitude == 0.0 {
				return
			}
			clientHello := tlsx.GetClientHello(packet)
			var sni = ""
			var tls = ""
			if clientHello != nil {
				sni = clientHello.SNI
				tls = clientHello.Version.String()
			} else {
				//检查http数据
				app := packet.ApplicationLayer()
				if app != nil {
					reader := bufio.NewReader(bytes.NewReader(app.Payload()))
					request, _ := http.ReadRequest(reader)
					if request != nil {
						sni = request.Host
						tls = "http"
					}
				}
			}

			if len(sni) == 0 {
				return
			}

			data := bean.Data{
				Latitude:    fmt.Sprintf("%f", localIpData.Latitude),
				Longitude:   fmt.Sprintf("%f", localIpData.Longitude),
				Countrycode: localIpData.Code,
				Country:     localIpData.Code,
				City:        localIpData.City,
				Org:         "本地网络",
				//-------------
				Latitude2:    fmt.Sprintf("%f", search.Latitude),
				Longitude2:   fmt.Sprintf("%f", search.Longitude),
				Countrycode2: search.Code,
				Country2:     search.Code,
				City2:        search.City,
				Type:         "ipviking.honey",
				Md5:          destData.Ip,
				Dport:        strconv.Itoa(destData.Port),
				Zerg:         "rush",
				Sni:          sni,
				Tls:          tls,
			}
			web.WsSend(data)
		}
	})
}

func initPcap() {
	var i = -1
	var ip = ""
	num := flag.Int("n", -1, "请输入网口编号")
	ipFlag := flag.String("p", "", "请输入本地外网IP")
	flag.Parse() // 解析参数
	i = *num
	ip = *ipFlag
	device := net.GetDevice()
	if i == -1 {
		reader := bufio.NewReader(os.Stdin)
		fmt.Println("网卡选择器、选择正确的物理网卡才能抓到数据,请输入数字选择：")
		for i := range device {
			fmt.Printf("【%d】:%s\n", i, device[i])
		}
		fmt.Print("-> ")
		text, _ := reader.ReadString('\n')
		text = strings.Replace(text, " ", "", -1)
		text = strings.Replace(text, "\r\n", "", -1)
		text = strings.Replace(text, "\n", "", -1)
		i, _ = strconv.Atoi(text)
	}
	deviceName := device[i]
	fmt.Println("你选择了【" + deviceName.Description + "】网卡")
	if len(ip) == 0 {
		ip = util.GetLocalIp()
	}
	fmt.Println("本地IP：" + ip)
	go startPacket(deviceName.Name, ip)
}

func main() {
	initPcap()
	fmt.Println("请访问：http://0.0.0.0:8080/static/")
	web.StartWeb(-1, staticFS)
}
